home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / disk-man / mtools-3.000 / mtools-3 / mtools-3.0 / mmove.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-08  |  5.7 KB  |  281 lines

  1. /*
  2.  * mmove.c
  3.  * Renames/moves an MSDOS file
  4.  *
  5.  */
  6.  
  7.  
  8. #define LOWERCASE
  9.  
  10. #include "sysincludes.h"
  11. #include "msdos.h"
  12. #include "mtools.h"
  13. #include "vfat.h"
  14. #include "streamcache.h"
  15. #include "plain_io.h"
  16. #include "nameclash.h"
  17. #include "file.h"
  18. #include "fs.h"
  19.  
  20. /*
  21.  * Preserve the file modification times after the fclose()
  22.  */
  23.  
  24. typedef struct Arg_t {
  25.     char *target;
  26.     char *fromname;
  27.     int nowarn;
  28.     int single;
  29.     int interactive;
  30.     int verbose;
  31.     int oldsyntax;
  32.     StreamCache_t sc;
  33.  
  34.     Stream_t *SrcDir;
  35.     int entry;
  36.     ClashHandling_t ch;
  37.     Stream_t *targetDir;
  38.     Stream_t *targetFs;
  39.     char *progname;
  40. } Arg_t;
  41.  
  42.  
  43. /*
  44.  * Open the named file for read, create the cluster chain, return the
  45.  * directory structure or NULL on error.
  46.  */
  47. static struct directory *renameit(char *dosname,
  48.                   char *longname,
  49.                   void *arg0,
  50.                   struct directory *dir)
  51. {
  52.     int entry;
  53.     struct directory parentdir;
  54.     Stream_t *Dir;
  55.     Arg_t *arg = (Arg_t *) arg0;
  56.     int fat;
  57.  
  58.  
  59.     *dir = arg->sc.dir;
  60.     strncpy(dir->name, dosname, 8);
  61.     strncpy(dir->ext, dosname + 8, 3);
  62.  
  63.     if( (dir->attr & 0x10) && arg->targetDir){
  64.         /* we have a directory here. Change its parent link */
  65.  
  66.         Dir = open_file( COPY(arg->targetFs), & arg->sc.dir);
  67.         entry = 0;
  68.         if(vfat_lookup(Dir, arg->targetFs,
  69.                    &parentdir, &entry, 0, "..", ACCEPT_DIR,
  70.                    NULL, NULL, NULL, NULL))
  71.             fprintf(stderr," Directory has no parent entry\n");
  72.         else {
  73.             entry--; /* rewind entry */
  74.             GET_DATA(arg->targetDir, 0, 0, 0, &fat);
  75.             parentdir.start[1] = (fat >> 8) & 0xff;
  76.             parentdir.start[0] = fat & 0xff;
  77.             dir_write(Dir, entry, &parentdir);
  78.             if(arg->verbose){
  79.                 fprintf(stderr,
  80.                     "Easy, isn't it? I wonder why DOS can't do this.\n");
  81.             }
  82.         }
  83.         FREE(&Dir);
  84.     }
  85.  
  86.     /* wipe out original entry */
  87.     arg->sc.dir.name[0] = DELMARK;
  88.     dir_write(arg->SrcDir, arg->entry, &arg->sc.dir);
  89.  
  90.     return dir;
  91. }
  92.  
  93.  
  94. static int rename_file(Stream_t *Dir, StreamCache_t *sc, int entry)
  95. /* write a messy DOS file to another messy DOS file */
  96. {
  97.     int result;
  98.     Stream_t *targetDir;
  99.     char *shortname, *longname;
  100.  
  101.     Arg_t * arg = (Arg_t *) (sc->arg);
  102.  
  103.     arg->SrcDir = Dir;
  104.     arg->entry = entry;
  105.     if(arg->oldsyntax){
  106.         targetDir = Dir;
  107.         arg->targetFs = sc->Fs;
  108.     } else
  109.         targetDir = arg->targetDir;
  110.  
  111.     if (targetDir == Dir){
  112.         arg->ch.ignore_entry = entry;
  113.         arg->ch.source = entry;
  114.     } else {
  115.         arg->ch.ignore_entry = -1;
  116.         arg->ch.source = -2;
  117.     }
  118.  
  119.  
  120.     if(arg->oldsyntax && !strcasecmp(sc->shortname, arg->fromname)){
  121.         longname = sc->longname;
  122.         shortname = arg->target;
  123.     } else {
  124.         longname = arg->target;
  125.         shortname = 0;
  126.     }
  127.  
  128.     result = mwrite_one(targetDir, arg->targetFs,
  129.                 arg->progname, longname, shortname,
  130.                 renameit, (void *)arg, &arg->ch);
  131.     if(result == 1)
  132.         return GOT_ONE;
  133.     else
  134.         return MISSED_ONE;
  135. }
  136.  
  137.  
  138. void mmove(int argc, char **argv, int oldsyntax)
  139. {
  140.     Stream_t *SubDir,*Dir, *Fs;
  141.     Arg_t arg;
  142.     int c, oops, ret;
  143.     char filename[VBUFSIZE];
  144.     char shortname[13];
  145.     char longname[VBUFSIZE];
  146.     char def_drive;
  147.     char *s;
  148.     int i;
  149.     int interactive;
  150.  
  151.     arg.progname = argv[0];
  152.  
  153.     /* get command line options */
  154.  
  155.     init_clash_handling(& arg.ch);
  156.  
  157.     oops = interactive = 0;
  158.  
  159.  
  160.     /* get command line options */
  161.     arg.verbose = 0;
  162.     arg.nowarn = 0;
  163.     arg.interactive = 0;
  164.     while ((c = getopt(argc, argv, "invorsamORSAM")) != EOF) {
  165.         switch (c) {
  166.             case 'i':
  167.                 arg.interactive = 1;
  168.                 break;
  169.             case 'n':
  170.                 arg.nowarn = 1;
  171.                 break;
  172.             case 'v':    /* dummy option for mcopy */
  173.                 arg.verbose = 1;
  174.                 break;
  175.             case '?':
  176.                 oops = 1;
  177.                 break;
  178.             default:
  179.                 if(handle_clash_options(&arg.ch, c))
  180.                     oops=1;
  181.                 break;
  182.         }
  183.     }
  184.  
  185.     if (oops || (argc - optind) < 2) {
  186.         fprintf(stderr,
  187.             "Mtools version %s, dated %s\n", mversion, mdate);
  188.         fprintf(stderr,
  189.             "Usage: %s [-itnmvV] file targetfile\n", argv[0]);
  190.         fprintf(stderr,
  191.             "       %s [-itnmvV] file [files...] target_directory\n", 
  192.             argv[0]);
  193.         cleanup_and_exit(1);
  194.     }
  195.  
  196.  
  197.     /* only 1 file to rename... */
  198.     arg.single = SINGLE;
  199.     
  200.     init_sc(&arg.sc);        
  201.     arg.sc.arg = (void *) &arg;
  202.     arg.sc.openflags = O_RDWR;
  203.  
  204.     /* look for a default drive */
  205.     def_drive = '\0';
  206.     for(i=optind; i<argc; i++)
  207.         if(argv[i][0] && argv[i][1] == ':' ){
  208.             if(!def_drive)
  209.                 def_drive = toupper(argv[i][0]);
  210.             else if(def_drive != toupper(argv[i][0])){
  211.                 fprintf(stderr,
  212.                     "Cannot move files across different drives\n");
  213.                 cleanup_and_exit(1);
  214.             }
  215.         }
  216.  
  217.     if(def_drive)
  218.         *(arg.sc.mcwd) = def_drive;
  219.  
  220.     if (oldsyntax && (argc - optind != 2 || strpbrk(":/", argv[argc-1])))
  221.         oldsyntax = 0;
  222.  
  223.     arg.oldsyntax = oldsyntax;
  224.  
  225.     if (!oldsyntax){
  226.         Dir = open_subdir(&arg.sc, argv[argc-1], O_RDWR, &Fs);
  227.         arg.targetFs = Fs;
  228.         if(!Dir){
  229.             fprintf(stderr,"Bad target\n");
  230.             cleanup_and_exit(1);
  231.         }
  232.         get_name(argv[argc-1], filename, arg.sc.mcwd);
  233.         SubDir = descend(Dir, Fs, filename, 0, 0);
  234.         if (!SubDir){
  235.             /* the last parameter is not a directory: take
  236.              * it as the new name */
  237.             if ( argc - optind != 2 ){
  238.                 fprintf(stderr,
  239.                     "%s: Too many arguments, or destination directory omitted\n", 
  240.                     argv[0]);
  241.                 cleanup_and_exit(1);
  242.             }
  243.             
  244.             arg.targetDir = Dir;
  245.             arg.sc.outname = 0; /* toss away source name */
  246.             arg.target = filename; /* store near name given as
  247.                         * target */
  248.             arg.single = 1;
  249.         } else {
  250.             arg.targetDir = SubDir;
  251.             FREE(&Dir);
  252.             arg.sc.outname = arg.target = filename;
  253.             arg.single = 0;
  254.         }
  255.     } else {
  256.         arg.fromname = argv[optind];
  257.         if(arg.fromname[0] && arg.fromname[1] == ':')
  258.             arg.fromname += 2;
  259.         s = strrchr(arg.fromname, '/');
  260.         if(s)
  261.             arg.fromname = s+1;
  262.         arg.sc.outname = filename;
  263.         arg.single = 0;
  264.         arg.targetDir = NULL;
  265.         arg.target = argv[argc-1];
  266.     }
  267.  
  268.     arg.sc.callback = rename_file;
  269.  
  270.     arg.sc.lookupflags = ACCEPT_PLAIN | ACCEPT_DIR | DO_OPEN | arg.single;
  271.  
  272.     arg.sc.longname = longname;
  273.     arg.sc.shortname = shortname;
  274.  
  275.     ret=main_loop(&arg.sc, argv[0], argv + optind, argc - optind - 1);
  276.     FREE(&arg.targetDir);
  277.     finish_sc(&arg.sc);
  278.  
  279.     cleanup_and_exit(ret);
  280. }
  281.